#ifndef vmidi_interface_h
#define vmidi_interface_h

#include "vmidi.h"

#include <string>
using namespace std;

namespace VMidi {

/**
  * @class VMidiInterface
  * @brief Public interface to VMidi
  */
class VMidiInterface {
  public:
    /**
      * Creates a new instance of VMidiInterface, depending on the
      * current implementation.
      */
    static inline VMidiInterface* getInstance();
    
    /**
      * Initializes the VMidi system.
      * This function will open the underlying MIDI API and probe for
      * available MIDI ports.
      * @throw An error string in case of error in the implementation.
      */
    virtual void initialize () throw(string) = 0;
    
    /**
      * Creates a new virtual port.
      * @param type Type of port (input or output).
      * @param name Name of the port. It is not necessarily unique.
      * @param portId (identifier of the newly created port, unique).
      * @throw An error string in case of error in the implementation.
      * @sa VMidiPortType
      */
    virtual void createVirtualPort (VMidiPortType type, const string& name, int&
        portId) throw(string) = 0;

    /**
     * Destroys a virtual port previously created with @sa createVirtualPort.
     * Note that it's impossible to destroy ports existing outside VMidi.
     * @param type Type of port (input or output).
     * @param portId identifier of the port to destroy.
     * @throw An error string in case of error in the implementation.
     */
    virtual void destroyVirtualPort (VMidiPortType type, int portId) throw(string) = 0;

    /**
      * Connects an input port to an output port.
      * After the connection is established, every information coming into
      * @p srcPortId will be redirected to port @dstPortId. This is
      * called MIDI Thru.
      * @param srcPortId source port identifier.
      * @param dstPortId destination port identifier.
      * @throw An error string in case of error in the implementation.
     */
    virtual void connectPorts (int srcPortId, int dstPortId) throw(string) = 0;

    /**
     * Disconnects the provided ports so that VMidi will not perform any MIDI
     * thru between them anymore.
     * @throw An error string in case of error in the implementation.
     */
    virtual void disconnectPorts (int srcPortId, int dstPortId) throw(string) = 0;

    /**
      * Allows to activate or deactive the current instance of VMidi.
      * If not active, all the declared port connexions will be inactive.
      */
    virtual void setActive (bool state) = 0;

    /**
      * Finalizes the VMidi system.
      * This function will close the underlying MIDI API and free the
      * list of declared MIDI ports (both real and virtual).
      * @throw An error string in case of error in the implementation.
      */
    virtual void finalize () throw(string) = 0;

    virtual ~VMidiInterface() {}

  protected:
    VMidiInterface()  {}
};

};

#endif

